package cn.iocoder.yudao.module.lfd.controller.admin.barber;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.iocoder.yudao.module.lfd.controller.admin.appointment.vo.AppointmentEnum;
import cn.iocoder.yudao.module.lfd.controller.admin.appointment.vo.AppointmentExportReqVO;
import cn.iocoder.yudao.module.lfd.controller.admin.schedule.vo.ScheduleExportReqVO;
import cn.iocoder.yudao.module.lfd.controller.admin.shop.vo.ShopRespVO;
import cn.iocoder.yudao.module.lfd.convert.schedule.ScheduleConvert;
import cn.iocoder.yudao.module.lfd.convert.shop.ShopConvert;
import cn.iocoder.yudao.module.lfd.dal.dataobject.appointment.AppointmentDO;
import cn.iocoder.yudao.module.lfd.dal.dataobject.schedule.ScheduleDO;
import cn.iocoder.yudao.module.lfd.dal.dataobject.shop.LfdShopDO;
import cn.iocoder.yudao.module.lfd.service.appointment.AppointmentService;
import cn.iocoder.yudao.module.lfd.service.schedule.ScheduleService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;

import javax.annotation.security.PermitAll;
import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.io.IOException;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;

import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;

import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;

import cn.iocoder.yudao.module.lfd.controller.admin.barber.vo.*;
import cn.iocoder.yudao.module.lfd.dal.dataobject.barber.BarberDO;
import cn.iocoder.yudao.module.lfd.convert.barber.BarberConvert;
import cn.iocoder.yudao.module.lfd.service.barber.BarberService;

@Tag(name = "管理后台 - 理发师")
@RestController
@RequestMapping("/lfd/barber")
@Validated
public class BarberController {

    @Resource
    private BarberService barberService;

    @PostMapping("/create")
    @Operation(summary = "创建理发师")
    @PreAuthorize("@ss.hasPermission('lfd:barber:create')")
    public CommonResult<Long> createBarber(@Valid @RequestBody BarberCreateReqVO createReqVO) {
        return success(barberService.createBarber(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新理发师")
    @PreAuthorize("@ss.hasPermission('lfd:barber:update')")
    public CommonResult<Boolean> updateBarber(@Valid @RequestBody BarberUpdateReqVO updateReqVO) {
        barberService.updateBarber(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除理发师")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('lfd:barber:delete')")
    public CommonResult<Boolean> deleteBarber(@RequestParam("id") Long id) {
        barberService.deleteBarber(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得理发师")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('lfd:barber:query')")
    public CommonResult<BarberRespVO> getBarber(@RequestParam("id") Long id) {
        BarberDO barber = barberService.getBarber(id);
        return success(BarberConvert.INSTANCE.convert(barber));
    }

    @GetMapping("/list")
    @Operation(summary = "获得理发师列表")
    @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
    @PreAuthorize("@ss.hasPermission('lfd:barber:query')")
    public CommonResult<List<BarberRespVO>> getBarberList(@RequestParam("ids") Collection<Long> ids) {
        List<BarberDO> list = barberService.getBarberList(ids);
        return success(BarberConvert.INSTANCE.convertList(list));
    }
    @GetMapping("/listAll")
    @Operation(summary = "获得理发师列表")
    @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
    public CommonResult<List<BarberRespVO>> listAll() {
        List<BarberDO> list = barberService.getBarberList(new BarberExportReqVO());
        return success(BarberConvert.INSTANCE.convertList(list));
    }


    @GetMapping("/page")
    @Operation(summary = "获得理发师分页")
    @PreAuthorize("@ss.hasPermission('lfd:barber:query')")
    public CommonResult<PageResult<BarberRespVO>> getBarberPage(@Valid BarberPageReqVO pageVO) {
        PageResult<BarberDO> pageResult = barberService.getBarberPage(pageVO);
        return success(BarberConvert.INSTANCE.convertPage(pageResult));
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出理发师 Excel")
    @PreAuthorize("@ss.hasPermission('lfd:barber:export')")
    @OperateLog(type = EXPORT)
    public void exportBarberExcel(@Valid BarberExportReqVO exportReqVO,
                                  HttpServletResponse response) throws IOException {
        List<BarberDO> list = barberService.getBarberList(exportReqVO);
        // 导出 Excel
        List<BarberExcelVO> datas = BarberConvert.INSTANCE.convertList02(list);
        ExcelUtils.write(response, "理发师.xls", "数据", BarberExcelVO.class, datas);
    }

    @Resource
    private AppointmentService appointmentService;
    @Resource
    private ScheduleService scheduleService;

    @GetMapping("/mini-list")
    @Operation(summary = "小程序获取店铺理发师接口")
    @PermitAll
    public CommonResult<List<BarberScheduleRespVO>> getMiniBarberList(@RequestParam Long shopId) {
        BarberExportReqVO vo = new BarberExportReqVO();
        vo.setShopId(shopId);
        List<BarberDO> list = barberService.getBarberList(vo);
        List<BarberScheduleRespVO> respVOs=new ArrayList<>();
        for (BarberDO barberDO : list) {
            List<ScheduleDO> scheduleList = getScheduleDOS(barberDO);
            List<AppointmentDO> appointmentList = getAppointmentDOS(shopId, barberDO);
            BarberScheduleRespVO respVO=new BarberScheduleRespVO();
            respVO.setWaitCount((long) appointmentList.size());
            convert(respVO,barberDO);
            convert(respVO,CollectionUtil.getFirst(scheduleList));
            respVOs.add(respVO);
        }

        return success(respVOs);
    }
    @GetMapping("/mini-get")
    @Operation(summary = "小程序获取店铺理单个发师接口")
    @PermitAll
    @Valid
    public CommonResult<BarberScheduleRespVO> getMiniGet(@RequestParam @NotNull Long shopId,@RequestParam(required = true) @NotNull Long barberId) {
        BarberExportReqVO vo = new BarberExportReqVO();
        vo.setShopId(shopId);
        List<BarberDO> list = barberService.getBarberList(vo);
        List<BarberScheduleRespVO> respVOs=new ArrayList<>();
        for (BarberDO barberDO : list) {
            if (!barberDO.getId().equals(barberId)) continue;
            List<ScheduleDO> scheduleList = getScheduleDOS(barberDO);
            List<AppointmentDO> appointmentList = getAppointmentDOS(shopId, barberDO);
            BarberScheduleRespVO respVO=new BarberScheduleRespVO();
            respVO.setWaitCount((long) appointmentList.size());
            convert(respVO,barberDO);
            convert(respVO,CollectionUtil.getFirst(scheduleList));
            respVOs.add(respVO);
        }
        return success(CollectionUtil.getFirst(respVOs));
    }

    private List<AppointmentDO> getAppointmentDOS(Long shopId, BarberDO barberDO) {
        AppointmentExportReqVO avo = new AppointmentExportReqVO();
        avo.setShopId(shopId);
        avo.setBarberId(barberDO.getId());
        avo.setStatus(AppointmentEnum.WAIT);
        avo.setHairDate(LocalDate.now());
        List<AppointmentDO> appointmentList = appointmentService.getAppointmentList(avo);
        return appointmentList;
    }

    private List<ScheduleDO> getScheduleDOS(BarberDO barberDO) {
        ScheduleExportReqVO vo1=new ScheduleExportReqVO();
        vo1.setBarberId(barberDO.getId());
        vo1.setShopId(barberDO.getShopId());
        vo1.setScheduleDate(LocalDateTime.now().toLocalDate());
        List<ScheduleDO> scheduleList = scheduleService.getScheduleList(vo1);
        return scheduleList;
    }

    public void convert(BarberScheduleRespVO respVO,ScheduleDO bean) {
        if (bean == null||"休息".equals(bean.getStatus())) {
            respVO.setStatus("休息");
            return;
        }
        respVO.setWork(true);
        respVO.setStartWork(bean.getStartWork());
        respVO.setEndWork(bean.getEndWork());
        respVO.setWeek(bean.getWeek());
        respVO.setStatus(bean.getStatus());
        respVO.setScheduleDate(bean.getScheduleDate());
    }

    public void convert(BarberScheduleRespVO respVO,BarberDO bean) {
        if (bean == null) {
            return;
        }
        respVO.setPhone(bean.getPhone());
        respVO.setLabel(bean.getLabel());
        respVO.setNickName(bean.getNickName());
        respVO.setSex(bean.getSex());
        respVO.setShopId(bean.getShopId());
        respVO.setAvatar(bean.getAvatar());
        respVO.setWorks(bean.getWorks());
        respVO.setId(bean.getId());
        respVO.setWaitTime(appointmentService.waitTime(bean.getShopId(), bean.getId()));
    }
}
